home *** CD-ROM | disk | FTP | other *** search
/ Leisure Game Pak / Leisure Game Pak.iso / lpgame1 / 04 / source / mynesgam.pas < prev    next >
Pascal/Delphi Source File  |  1994-08-17  |  20KB  |  522 lines

  1. (*  .....................................................................  *)
  2. (*  :    file        :  MYNESGAM.PAS                                 :  *)
  3. (*  :      contents    :  the game routines for MYNES!            :  *)
  4. (*  :    last update    :  06-JUL-93                                    :  *)
  5. (*  :...................:...............................................:  *)
  6. (*
  7.     - reveal_tile, mark_tile
  8.         - get_computer_move, get_mouse_button
  9.           get_field_action, get_control_action, play_game
  10. *)
  11.  
  12. (*  reveal_tile uncovers the tile in col, row unless it is already uncovered
  13.     (it is called by uncover_hidden_0s with a pos that is already uncovered)*)
  14. PROCEDURE    reveal_tile(VAR scene      : SCENE_TYPE;
  15.                 col, row : COL_ROW_TYPE);
  16.  
  17. (*  uncover_hidden0  reveales a contiguous area of hidden0's  *)
  18. (*  USES: get_tile_pos(5), reveal_tile(3), SetFillStyle(2), Bar(4),
  19.             MouseUpdate(4), ShowMouse() *)
  20. PROCEDURE       uncover_hidden0s(VAR scene : SCENE_TYPE;
  21.                                  col, row : COL_ROW_TYPE);
  22. VAR    x, y    : WORD;
  23. BEGIN
  24.     IF  (LookIsPL)  THEN
  25.         BEGIN
  26.            (*  draw it just like the other visible tiles  *)
  27.        draw_tile(scene, play_tile, col, row, VISIBLE0);
  28.            (* 1.3.93 don't reveal 8 directions in PL-look ... it's not fair *)
  29.        {
  30.         reveal_tile(scene, real_col(scene, PRED(col)), real_row(scene, PRED(row)));  (* NWest *)
  31.         reveal_tile(scene, real_col(scene, SUCC(col)), real_row(scene, PRED(row)));  (* NEast *)
  32.         reveal_tile(scene, real_col(scene, PRED(col)), real_row(scene, SUCC(row)));  (* SWest *)
  33.         reveal_tile(scene, real_col(scene, SUCC(col)), real_row(scene, SUCC(row)));  (* SEast *)
  34.            }
  35.         END
  36.         ELSE
  37.         BEGIN    (*  for MP-look: draw a black box  *)
  38.            get_tile_pos(scene, col, row, x, y);
  39.            SetFillStyle(SOLIDFILL, BLACK);
  40.                Bar(x + 2, y + 2,
  41.                x + scene.Size.x - 3, y + scene.Size.y - 3);
  42.     END;
  43.  
  44.         (*  continue reveal_tile in all 4 (not 8) directions
  45.         use real cols/rows to make reveal continue its work on the other
  46.         side of the playfield as it reaches an edge  *)
  47.     reveal_tile(scene, real_col(scene, PRED(col)), row);  (* West *)
  48.     reveal_tile(scene, real_col(scene, SUCC(col)), row);  (* East *)
  49.     reveal_tile(scene, col, real_row(scene, PRED(row)));  (* North *)
  50.     reveal_tile(scene, col, real_row(scene, SUCC(row)));  (* South *)
  51. END;    (*  uncover_hidden0s  *)
  52.  
  53. CONST    BADMARK = 2;    (* points lost when removing a mark *)
  54. VAR    contents : CONTENTS_TYPE;
  55.     but      : BYTE;
  56. BEGIN      (*  reveal_tile  *)
  57.     contents := playfield[row, col];
  58.         IF  (contents IN HIDDEN + MARKED)  THEN
  59.     BEGIN
  60.         HideMouse;
  61.         (*  LeastCol/Row is the first col/row that has to be examined ...
  62.                 you needn't examine positions that cannot have changed  *)
  63.             IF  (col < LeastCol)  THEN
  64.             LeastCol := max(0, PRED(col));
  65.  
  66.               IF  (contents in HIDDEN)  THEN
  67.                 BEGIN
  68.                         (*  count the tiles to check for 'WON' *)
  69.                         IF  (Tiles_left > 0)  THEN
  70.                     DEC(Tiles_left);
  71.                         refresh_bar(DONE_BAR, Tiles_left, TilesToReveal);
  72.                         DEC(playfield[row, col], ORD(hidden0) - ORD(visible0));
  73.  
  74.                         IF  (contents = hidden0)  THEN
  75.                                 uncover_hidden0s(scene, col, row)
  76.                         ELSE  BEGIN
  77.                                 draw_tile(scene, play_tile, col, row, playfield[row, col]);
  78.                                 IF  (contents = hidden_mine)  THEN
  79.                     BEGIN
  80.                                     (*  show some flashes  *)
  81.                         GameStatus := BLASTED;
  82.                                         MyDelay(1000);
  83.                                         explode(scene, col, row);
  84.                                 END  (* IF *)
  85.                                 ELSE
  86.                         INC (Score, ORD(contents) - ORD(hidden0));
  87.                         END;  (* ELSE *)
  88.                         ShowMouse;
  89.                 END  (* IF (contents... *)
  90.                 ELSE IF  (contents IN MARKED)  THEN
  91.                 BEGIN
  92.                     (*  retract this mark and show a hidden tile  *)
  93.                         DEC(MarkedTiles);
  94.                         IF  (Score > BADMARK)  THEN
  95.                 DEC(Score, BADMARK)
  96.             ELSE
  97.                 Score := 0;
  98.  
  99.                         DEC(playfield[row, col], ORD(marked0) - ORD(hidden0));
  100.                         draw_tile(scene, play_tile, col, row, hidden0);
  101.                     ShowMouse;
  102.  
  103.                         (*  wait until left mouse button released  *)
  104.                 but := WaitMouseButtons(TRUE, FALSE, FALSE, FALSE);
  105.                 END;  (* ELSE IF *)
  106.         END;  (* IF *)
  107. END;    (*  reveal_tile  *)
  108.  
  109.  
  110. (*  mark a tile  *)
  111. PROCEDURE    mark_tile(VAR scene     : SCENE_TYPE;
  112.                         col, row     : COL_ROW_TYPE);
  113. BEGIN
  114.         (*  LeastCol/Row is the first col/row that has to be examined ...
  115.             you needn't examine positions that cannot have changed  *)
  116.         IF  (col < LeastCol)  THEN
  117.         LeastCol := max(0, PRED(col));
  118.  
  119.     INC(MarkedTiles);
  120.         DEC(playfield[row, col], ORD(hidden0) - ORD(marked0));
  121.         (* all markers look alike -> show marked0 *)
  122.         HideMouse;
  123.         draw_tile(scene, play_tile, col, row, marked0);
  124.         ShowMouse;
  125. END;    (*  mark_tile  *)
  126.  
  127.  
  128. (*  produce a clicking noise simulating a mousebutton  *)
  129. PROCEDURE    computerclick(high : BOOLEAN);
  130. BEGIN
  131.     IF  (SoundIsON)  THEN
  132.         BEGIN
  133.         IF  high  THEN
  134.            Sound(5600)
  135.                 ELSE
  136.            Sound(5200);
  137.         Delay(1);  NoSound;
  138.         END;
  139. END;    (*  computerclick  *)
  140.  
  141.  
  142. FUNCTION    get_computer_move(VAR  scene : SCENE_TYPE;
  143.                   VAR  mx, my: WORD) : WORD;
  144.  
  145. TYPE    COORDS_LIST_TYPE = ARRAY [1..8] OF COORDS_TYPE;
  146.  
  147. CONST    to_reveal_list : COORDS_LIST_TYPE =
  148.         ((x:0;y:0),(x:0;y:0),(x:0;y:0),(x:0;y:0),
  149.          (x:0;y:0),(x:0;y:0),(x:0;y:0),(x:0;y:0));
  150.          to_mark_list   : COORDS_LIST_TYPE =
  151.         ((x:0;y:0),(x:0;y:0),(x:0;y:0),(x:0;y:0),
  152.          (x:0;y:0),(x:0;y:0),(x:0;y:0),(x:0;y:0));
  153.         to_reveal : BYTE = 0;
  154.         to_mark      : BYTE = 0;
  155.  
  156. VAR    col, colj,
  157.     row, rowi,
  158.     randcol, randrow: COL_ROW_TYPE;
  159.         marked_list,
  160.     hidden_list    : COORDS_LIST_TYPE;
  161.         no_tiles    : BOOLEAN;
  162.         contents    : CONTENTS_TYPE;
  163.         value,
  164.     hiddens,
  165.     markeds         : BYTE;
  166.         mdx, mdy    : INTEGER;
  167.     wait        : WORD;
  168.         reveal_sound    : BOOLEAN;
  169.  
  170. PROCEDURE    count_hidden_marked (col, row : COL_ROW_TYPE);
  171. VAR    r_row, r_col,
  172.     rowi, colj    : COL_ROW_TYPE;
  173.     n_cont          : CONTENTS_TYPE;
  174. BEGIN
  175.         hiddens := 0;
  176.         markeds := 0;
  177.         (*  columns as outer loop to keep same columns together an save mousemoves *)
  178.     FOR  colj := PRED(col) TO  SUCC(col)  DO
  179.     BEGIN
  180.             r_col := real_col(scene, colj);
  181.             FOR  rowi := PRED(row) TO  SUCC(row)  DO
  182.             BEGIN
  183.                 r_row := real_row(scene, rowi);
  184.                         n_cont := playfield[r_row, r_col];
  185.                         IF  (n_cont IN HIDDEN)  THEN
  186.                         BEGIN
  187.                                 INC(hiddens);
  188.                             hidden_list[hiddens].x := r_col;
  189.                             hidden_list[hiddens].y := r_row;
  190.                         END  (* IF *)
  191.                         ELSE IF  (n_cont IN MARKED)  THEN
  192.                         BEGIN
  193.                                 INC(markeds);
  194.                 marked_list[markeds].x := r_col;
  195.                                 marked_list[markeds].y := r_row;
  196.                         END;  (* IF *)
  197.         END; (* FOR rowi *)
  198.     END; (* FOR colj *)
  199. END;    (*  count_hidden_marked  *)
  200.  
  201. BEGIN   (* get_computer_move *)
  202.     IF  (GameStatus = DEMO_START)  THEN
  203.         BEGIN
  204.             to_reveal := 0;
  205.         to_mark := 0;
  206.                 GameStatus := DEMO;    (* the next move will be normal *)
  207.         END;  (* IF *)
  208.  
  209.         no_tiles := (to_reveal + to_mark = 0);
  210.  
  211.         (* compute waitstates depending on Speed and Level *)
  212.         wait := SPEED_FACTOR[Speed] * 5;
  213.         IF  (no_tiles)  THEN  wait := Random(wait * 6) + wait
  214.                    ELSE  wait := Random(wait) + wait DIV 2;
  215.  
  216.         (*  the outer loop is on cols to limit mouse movement  *)
  217.     colj := LeastCol;
  218.     WHILE  (no_tiles)  AND  (colj < scene.NumCols)   DO
  219.     BEGIN
  220.             rowi := 0;
  221.             WHILE   (no_tiles)  AND  (rowi < scene.NumRows)  DO
  222.                 BEGIN
  223.                         contents := playfield[rowi, colj];
  224.                         IF  (contents IN VISIBLE)  THEN
  225.                         BEGIN
  226.                                 value := ORD(contents) - ORD(visible0);
  227.                                 count_hidden_marked(colj, rowi);
  228.                                 IF  (value = markeds + hiddens)  AND  (hiddens > 0)  THEN
  229.                 BEGIN
  230.                                         to_mark_list := hidden_list;
  231.                                         to_mark := hiddens;
  232.                                         no_tiles := FALSE;
  233.                                 END  (* IF *)
  234.                                 ELSE IF  (value = markeds)  AND  (hiddens > 0)  THEN
  235.                 BEGIN
  236.                                         to_reveal_list := hidden_list;
  237.                                         to_reveal := hiddens;
  238.                                         no_tiles := FALSE;
  239.                                 END  (* ELSE IF *)
  240.                                 ELSE IF  (value < markeds)  THEN
  241.                 BEGIN
  242.                                         to_reveal_list := marked_list;
  243.                                         to_reveal := markeds;
  244.                                         no_tiles := FALSE;
  245.                                 END  (* ELSE IF *)
  246.             END;  (* IF contents *)
  247.                     INC(rowi);
  248.         END;  (* WHILE colj *)
  249.             (*  all cols before colj were without a result  *)
  250.             LeastCol := colj;
  251.                 INC(colj);
  252.     END;  (* WHILE rowi *)
  253.  
  254.     randrow := Random(scene.NumRows);
  255.     randcol := Random(scene.NumCols);
  256.         rowi := 0;
  257.         IF  (no_tiles)  THEN  INC(wait, 300);    (* some more uncertainty *)
  258.  
  259.         (* search for a random hidden tile to be revealed, or if no hidden
  260.        can be found, simply reveal a random marked tile *)
  261.     WHILE  (no_tiles)  AND  (rowi < scene.NumRows)  DO
  262.     BEGIN
  263.             row := (randrow + rowi) MOD scene.NumRows;
  264.             colj := 0;
  265.             WHILE  (no_tiles)  AND   (colj < scene.NumCols)  DO
  266.                 BEGIN
  267.                     col := (randcol + colj) MOD scene.NumCols;
  268.  
  269.                         contents := playfield[row, col];
  270.                         IF  (contents IN HIDDEN)  THEN
  271.                         BEGIN
  272.                     to_reveal := 1;
  273.                                 to_reveal_list[1].x := col;
  274.                                 to_reveal_list[1].y := row;
  275.                                 no_tiles := FALSE;
  276.                         END  (* IF *)
  277.                         ELSE IF (contents IN MARKED)  THEN
  278.                         BEGIN
  279.                     to_reveal := 1;
  280.                                 to_reveal_list[1].x := col;
  281.                                 to_reveal_list[1].y := row;
  282.                         END;  (* ELSE IF *)
  283.                         INC(colj);
  284.         END;  (* WHILE colj *)
  285.                 INC(rowi);
  286.     END;  (* WHILE rowi *)
  287.  
  288.         (* as we reach this point, we know that there is something
  289.            to_reveal  and/or  to_mark, first we do the reveals then the marks *)
  290.  
  291.     IF  (to_reveal > 0)  THEN
  292.         BEGIN
  293.                 get_computer_move := LEFTMOUSEBUTTON;
  294.         col := to_reveal_list[to_reveal].x;    (* col *)
  295.         row := to_reveal_list[to_reveal].y;    (* row *)
  296.                 DEC(to_reveal);
  297.             reveal_sound := TRUE;
  298.         END
  299.         ELSE IF  (to_mark > 0)  THEN
  300.         BEGIN
  301.                 get_computer_move := RIGHTMOUSEBUTTON;
  302.         col := to_mark_list[to_mark].x;    (* col *)
  303.         row := to_mark_list[to_mark].y;    (* row *)
  304.                 DEC(to_mark);
  305.             reveal_sound := FALSE;
  306.     END;
  307.  
  308.         (*  search is over ... if tile isn't revealed yet, then ...
  309.         let's hesitate for some millisecs
  310.         note: if a tile in to_reveal_list is revealed by uncover_hidden0s
  311.               it stays in to_reveal_list even though it is visible  *)
  312.  
  313.         IF  (playfield [row, col] IN HIDDEN + MARKED)  THEN
  314.         BEGIN
  315.             MouseMove(mdx, mdy);    (*  watch mouse ... *)
  316.                 IF (ABS(mdx) + ABS(mdy) <= 60)  THEN
  317.                 BEGIN
  318.                     IF  Speed < LASTSPEED  THEN MyDelay(wait);
  319.             MouseMove(mdx, mdy);
  320.                 END;  (* IF *)
  321.  
  322.             (*  drag mouse to the middle of this tile  *)
  323.             get_tile_middle(scene, col, row, mx, my);
  324.  
  325.                 IF (ABS(mdx) + ABS(mdy) > 60)  OR
  326.                NOT(DragMouse(mx, my, SOFT_DRAG))  THEN
  327.             BEGIN    (*  cancel demo mode  *)
  328.                     GameStatus := PLAY;
  329.             (*  computer presses no button  *)
  330.                         get_computer_move := 0;
  331.  
  332.                     GAME_PAUSE_GADGET.show;
  333.                 GAME_QUIT_GADGET.show;
  334.                 GAME_DEMO_GADGET.show;
  335.         END  (* IF ABS *)
  336.                 ELSE
  337.                 BEGIN
  338.             MyDelay(2 * SPEED_FACTOR[Speed]);
  339.                         computerclick(reveal_sound);
  340.                 END;
  341.         END;  (* IF playfield *)
  342. END;    (* get_computer_move *)
  343.  
  344.  
  345. (*  get_mouse_button  returns   as Time_left seconds have passed, or
  346.                 as one of the mousebuttons is pressed
  347.                 the time remaining  *)
  348. FUNCTION        get_mouse_button (VAR  scene : SCENE_TYPE;
  349.                   VAR  mx, my, mbut : WORD) : INTEGER;
  350.  
  351. CONST    last_time : WORD = 0;
  352. VAR    Time_left : INTEGER;
  353. BEGIN    (*  get_mouse_button  *)
  354.  
  355.    REPEAT
  356.       Time_left := PLAYTIMER.read;
  357.       IF  ESC_pressed  THEN
  358.       BEGIN
  359.         GameStatus := QUIT;    (*  exit this function/game  *)
  360.         mbut := NO_MOUSEBUTTON;    (* no button pressed *)
  361.       END (* IF *)
  362.       ELSE
  363.       BEGIN
  364.      IF  (GameStatus IN [PLAY, DEMO, DEMO_START])  THEN
  365.      BEGIN
  366.          IF  (last_time > Time_left)  THEN
  367.              refresh_bar(TIME_BAR, Time_left, scene.TimeLimit);
  368.  
  369.                  last_time := Time_left;
  370.          END;  (* IF *)
  371.          IF  (GameStatus IN [DEMO, DEMO_START])  THEN
  372.                  mbut := get_computer_move(scene, mx, my)
  373.          ELSE
  374.                  mbut := GetMousePos(mx, my);
  375.       END; (* ELSE *)
  376.  
  377.    UNTIL  (Time_left <= 0)         OR
  378.          (mbut = LEFTMOUSEBUTTON)    OR
  379.       (mbut = RIGHTMOUSEBUTTON)    OR
  380.       (GameStatus = QUIT);
  381.    get_mouse_button := Time_left;
  382. END;    (*  get_mouse_button  *)
  383.  
  384.  
  385. (*  get_field_action returns TRUE if mousebutton is pressed on-field else FALSE
  386.     GameStatus must be the actual status  (i.e. PLAY or DEMO)
  387.     on its return GameStatus contains the new status  (PLAY, DEMO, BLASTED) *)
  388.  
  389. FUNCTION        get_field_action(scene          : SCENE_TYPE;
  390.                                  mx, my, mbut   : INTEGER) : BOOLEAN;
  391.  
  392. VAR     contents : CONTENTS_TYPE;
  393.         col, row : COL_ROW_TYPE;
  394.     original_time : LONGINT;
  395. BEGIN
  396.         DEC(mx, scene.Origin.x);    (* that's why mx,my are INTEGERs *)
  397.         DEC(my, scene.Origin.y);    (* without this they should be WORDs *)
  398.  
  399.         col := mx DIV SUCC(scene.Size.x);
  400.         row := my DIV SUCC(scene.Size.y);
  401.  
  402.         IF  (in_rect(col, row, 0, 0, scene.NumCols, scene.NumRows))  THEN
  403.         BEGIN
  404.                 get_field_action := TRUE;       (* mouse is on field *)
  405.                 IF  (mx MOD SUCC(scene.Size.x) < scene.Size.x) AND
  406.                     (my MOD SUCC(scene.Size.y) < scene.Size.y)  THEN
  407.                 BEGIN
  408.                         contents := playfield[row,col];
  409.  
  410.                         IF  (mbut = LEFTMOUSEBUTTON) AND (contents IN HIDDEN + MARKED)  THEN
  411.                         BEGIN
  412.                 (* if someone reveals a tile then he plays ...
  413.                    check GameStatus first, as it may be changed
  414.                    by reveal_tile (BLASTED, WON)  *)
  415.                             IF  (GameStatus = PLAY)  THEN
  416.                                        ManPlayed := TRUE
  417.                             ELSE
  418.                                     ComputerPlayed := TRUE;
  419.                             reveal_tile(scene, col, row);
  420.                         END
  421.                         ELSE IF (mbut = RIGHTMOUSEBUTTON) AND (contents IN HIDDEN)  THEN
  422.                             mark_tile(scene, col, row);
  423.  
  424.                         { ELSE    flash; (* illegal input *) }
  425.             (*  test for WON, all three conditions are necessary  *)
  426.                     IF  (Tiles_left = 0)              AND
  427.                             (MarkedTiles = scene.NumMines) AND
  428.                     (GameStatus <> BLASTED)       THEN
  429.             BEGIN
  430.                 GameStatus := WON;
  431.                                 (* increase score because of WON *)
  432.                                 (* Score += 2 * (OriginalTimeLimit - TimeUsed) *)
  433.                                 (* note: we take PRED(...) to give the faster
  434.                          speeds a slight advantage *)
  435.                                 original_time := scene.TimeLimit * 60 DIV PRED(SPEED_FACTOR[Speed]);
  436.                                 INC(Score, 2*(original_time - (scene.TimeLimit - PLAYTIMER.read)));
  437.                         END;  (* IF *)
  438.                 END;  (* IF *)
  439.         END  (* IF *)
  440.         ELSE    get_field_action := FALSE;
  441. END;    (*  get_field_action  *)
  442.  
  443.  
  444. PROCEDURE    get_control_action;
  445. VAR    but : BYTE;
  446.     dmx, dmy : INTEGER;    (* to reset mousemoves *)
  447. BEGIN
  448.     IF  (GAME_QUIT_GADGET.handle_mouse_click)  THEN
  449.             GameStatus := QUIT
  450.  
  451.         ELSE IF  (GAME_PAUSE_GADGET.handle_mouse_click)  THEN
  452.         BEGIN
  453.             (*  reduce brightness, to prevent player from looking  *)
  454.                 dim_palette(20, SLOW_DIM);
  455.                 PLAYTIMER.stop;
  456.  
  457.                 (*  press either button to continue  *)
  458.                 but := WaitMouseButtons(FALSE, TRUE, TRUE, FALSE);
  459.  
  460.         PLAYTIMER.restart;
  461.                 dim_palette(100, SLOW_DIM);
  462.         END  (* ELSE IF *)
  463.  
  464.         ELSE IF  (GAME_DEMO_GADGET.handle_mouse_click)  THEN
  465.         BEGIN
  466.               GameStatus := DEMO_START;    (* 1st move ! *)
  467.             GAME_PAUSE_GADGET.hide;
  468.         GAME_QUIT_GADGET.hide;
  469.         GAME_DEMO_GADGET.hide;
  470.             MouseMove(dmx, dmy);        (* reset movecounter *)
  471.         END;  (* ELSE IF *)
  472.  
  473. END;    (*  get_control_action  *)
  474.  
  475.  
  476. (*  this is the main playing loop  *)
  477. PROCEDURE       play_game(scene : SCENE_TYPE);
  478. VAR     mrow, mcol    : COL_ROW_TYPE;
  479.     mx, my, mbut     : WORD;
  480.         dummy        : INTEGER;    (* for MouseMove *)
  481. BEGIN
  482.         MarkedTiles     := 0;        (* initialize counters *)
  483.     TilesToReveal     := scene.NumRows * scene.NumCols - scene.NumMines;
  484.         Tiles_left     := TilesToReveal;
  485.         LeastCol     := 0;
  486.         Score         := 0;
  487.         (* noone made a move so far ... *)
  488.         ComputerPlayed     := FALSE;
  489.         ManPlayed       := FALSE;
  490.  
  491.         (*  get a safe starting point ... *)
  492.         REPEAT
  493.                 mcol := Random(scene.NumCols);
  494.                 mrow := Random(scene.NumRows);
  495.         UNTIL  (playfield[mrow, mcol] <> hidden_mine);
  496.  
  497.         (*  place mouse in the middle of this tile  *)
  498.         get_tile_middle(scene, mcol, mrow, mx, my);
  499.         SetMousePos(mx, my);
  500.         MouseMove(dummy, dummy);    (* reset mousemoves *)
  501.  
  502.     (*  start timer with TimeLimit seconds left *)
  503.         PLAYTIMER.init(scene.TimeLimit);
  504.  
  505.         (*  if DEMO then reveal this (safe) tile  *)
  506.         IF  (GameStatus = DEMO_START)  THEN
  507.         BEGIN
  508.             MyDelay(500);
  509.                 computerclick(true);    (* some mouseclick-sound *)
  510.             reveal_tile(scene, mcol, mrow);
  511.         END;  (* IF *)
  512.  
  513.         REPEAT
  514.         IF (get_mouse_button(scene, mx, my, mbut) <= 0) THEN
  515.                     GameStatus := TIMEOUT
  516.             ELSE
  517.             IF  NOT(get_field_action(scene, mx, my, mbut))  THEN
  518.                 get_control_action;
  519.  
  520.         UNTIL   GameStatus IN [BLASTED, QUIT, TIMEOUT, WON];
  521. END;    (*  play_game  *)
  522.